const url = require("url");
const Layer = require("./layer");
const Route = require("./route");
const methods = require("methods");
function Router() {
  this.stack = [];
}
methods.forEach((method) => {
  Router.prototype[method] = function (path, handlers) {
    const route = new Route();
    const layer = new Layer(path, route.dispatch.bind(route));

    layer.route = route; // 当调用路由方法时，会产生一个route

    this.stack.push(layer);
    route[method](handlers); // 让里层的route 记住用户的方法
  };
});
Router.prototype.use = function (path, ...handlers) {
  if (typeof path !== "string") {
    // path 就是路径
    handlers.unshift(path); // 这里用户没有写路径
    path = "/";
  }
  handlers.forEach((handler) => {
    let layer = new Layer(path, handler);
    layer.route = undefined;
    this.stack.push(layer); // 将layer 放到stack中
  });
};

Router.prototype.handle = function (req, res, out) {
  let { pathname } = url.parse(req.url);
  let idx = 0;

  const next = (err) => {
    if (idx >= this.stack.length) return out(); // 递归的终止条件
    let layer = this.stack[idx++];
    if (err) {
      if (!layer.route) {
        layer.handle_error(err, req, res, next);
      } else {
        next(err); // 如果是路由，需要继续向下执行
      }
    } else {
      if (layer.match(pathname)) {
        // layer.params
        req.params = layer.params || {};
        if (!layer.route) {
          if (layer.handler.length !== 4) {
            // 正常情况下 不走错误处理中间件
            layer.handle_request(req, res, next);
          } else {
            next();
          }
        } else {
          // route.dispatch
          // 在看这个layer 对应的route 上面的methods  是否包含当前请求的methods
          if (layer.route.methods[req.method.toLowerCase()]) {
            layer.handle_request(req, res, next);
          } else {
            next();
          }
        }
      } else {
        next();
      }
    }
  };
  next();
};

module.exports = Router;

// 1.路由就是匹配路径以及方法的，都满足才执行
